# -*- coding: utf-8 -*-
"""
推荐系统服务层

负责处理商品推荐的业务逻辑
"""
import random
from typing import List, Dict, Any, Set
from app.repositories.recommendation_repository import RecommendationRepository


class RecommendationService:
    """推荐系统服务类"""
    
    def __init__(self):
        self.recommendation_repo = RecommendationRepository()
    
    def get_recommendations_for_user(self, user_id: str, limit: int = 20) -> Dict[str, Any]:
        """为用户生成个性化推荐"""
        try:
            recommendations = []
            recommended_goods_ids = set()
            
            # 1. 基于购买历史的推荐 (占比30%)
            purchase_recommendations = self._get_purchase_based_recommendations(
                user_id, int(limit * 0.3), recommended_goods_ids
            )
            recommendations.extend(purchase_recommendations)
            
            # 2. 基于购物车的推荐 (占比25%)
            cart_recommendations = self._get_cart_based_recommendations(
                user_id, int(limit * 0.25), recommended_goods_ids
            )
            recommendations.extend(cart_recommendations)
            
            # 3. 热门商品推荐 (占比25%)
            popular_recommendations = self._get_popular_recommendations(
                int(limit * 0.25), recommended_goods_ids
            )
            recommendations.extend(popular_recommendations)
            
            # 4. 补充随机推荐 (填满剩余位置)
            remaining_count = limit - len(recommendations)
            if remaining_count > 0:
                random_recommendations = self._get_random_recommendations(
                    remaining_count, recommended_goods_ids
                )
                recommendations.extend(random_recommendations)
            
            # 随机打乱推荐顺序
            random.shuffle(recommendations)
            
            return {
                "success": True,
                "data": {
                    "recommendations": recommendations[:limit],
                    "total_count": len(recommendations),
                    "algorithm_info": {
                        "purchase_based": len(purchase_recommendations),
                        "cart_based": len(cart_recommendations),
                        "popular_based": len(popular_recommendations),
                        "random": len(recommendations) - len(purchase_recommendations) - len(cart_recommendations) - len(popular_recommendations)
                    }
                }
            }
            
        except Exception as e:
            return {"success": False, "message": f"生成推荐失败: {str(e)}"}
    
    def get_similar_goods(self, goods_id: str, limit: int = 10) -> Dict[str, Any]:
        """获取相似商品推荐"""
        try:
            similar_goods = self.recommendation_repo.get_similar_goods(goods_id, limit)
            
            # 格式化商品信息
            formatted_goods = []
            for goods in similar_goods:
                formatted_goods.append(self._format_goods_info(goods))
            
            return {
                "success": True,
                "data": {
                    "similar_goods": formatted_goods,
                    "total_count": len(formatted_goods)
                }
            }
            
        except Exception as e:
            return {"success": False, "message": f"获取相似商品失败: {str(e)}"}
    
    def get_popular_goods(self, limit: int = 20) -> Dict[str, Any]:
        """获取热门商品"""
        try:
            popular_goods = self.recommendation_repo.get_popular_goods(limit=limit)
            
            # 格式化商品信息
            formatted_goods = []
            for goods in popular_goods:
                goods_info = self._format_goods_info(goods)
                goods_info['sales_count'] = goods.get('total_sales', 0)
                formatted_goods.append(goods_info)
            
            return {
                "success": True,
                "data": {
                    "popular_goods": formatted_goods,
                    "total_count": len(formatted_goods)
                }
            }
            
        except Exception as e:
            return {"success": False, "message": f"获取热门商品失败: {str(e)}"}
    
    def _get_purchase_based_recommendations(self, user_id: str, limit: int, 
                                          excluded_ids: Set[str]) -> List[Dict[str, Any]]:
        """基于购买历史的推荐"""
        recommendations = []
        
        # 获取用户购买历史
        purchase_history = self.recommendation_repo.get_user_purchase_history(user_id, 20)
        
        # 基于购买的商品类别和品牌推荐
        for history in purchase_history[:5]:  # 只取前5个最常购买的
            class_name = history.get('class_name')
            brand_name = history.get('brand_name')
            
            if class_name:
                # 同类别商品推荐
                category_goods = self.recommendation_repo.get_goods_by_category(
                    class_name, None, list(excluded_ids), limit//2
                )
                for goods in category_goods:
                    if len(recommendations) >= limit:
                        break
                    goods_info = self._format_goods_info(goods)
                    goods_info['recommend_reason'] = f'与您购买的{class_name}商品相似'
                    recommendations.append(goods_info)
                    excluded_ids.add(goods['goods_id'])
            
            if brand_name and len(recommendations) < limit:
                # 同品牌商品推荐
                brand_goods = self.recommendation_repo.get_goods_by_brand(
                    brand_name, list(excluded_ids), limit//2
                )
                for goods in brand_goods:
                    if len(recommendations) >= limit:
                        break
                    goods_info = self._format_goods_info(goods)
                    goods_info['recommend_reason'] = f'您喜欢的{brand_name}品牌商品'
                    recommendations.append(goods_info)
                    excluded_ids.add(goods['goods_id'])
        
        return recommendations
    
    def _get_cart_based_recommendations(self, user_id: str, limit: int, 
                                       excluded_ids: Set[str]) -> List[Dict[str, Any]]:
        """基于购物车的推荐"""
        recommendations = []
        
        # 获取购物车中的商品类别
        cart_categories = self.recommendation_repo.get_user_cart_categories(user_id)
        
        for category in cart_categories[:3]:  # 只取前3个最常见的类别
            class_name = category.get('class_name')
            brand_name = category.get('brand_name')
            
            if class_name:
                # 推荐同类别的其他商品
                category_goods = self.recommendation_repo.get_goods_by_category(
                    class_name, brand_name, list(excluded_ids), limit//2
                )
                for goods in category_goods:
                    if len(recommendations) >= limit:
                        break
                    goods_info = self._format_goods_info(goods)
                    goods_info['recommend_reason'] = f'购物车中有{class_name}商品'
                    recommendations.append(goods_info)
                    excluded_ids.add(goods['goods_id'])
        
        return recommendations
    
    def _get_popular_recommendations(self, limit: int, excluded_ids: Set[str]) -> List[Dict[str, Any]]:
        """热门商品推荐"""
        recommendations = []
        
        popular_goods = self.recommendation_repo.get_popular_goods(
            list(excluded_ids), limit
        )
        
        for goods in popular_goods:
            goods_info = self._format_goods_info(goods)
            goods_info['recommend_reason'] = '热门商品'
            goods_info['sales_count'] = goods.get('total_sales', 0)
            recommendations.append(goods_info)
            excluded_ids.add(goods['goods_id'])
        
        return recommendations
    
    def _get_random_recommendations(self, limit: int, excluded_ids: Set[str]) -> List[Dict[str, Any]]:
        """随机商品推荐"""
        recommendations = []
        
        # 随机获取一些类别的商品
        categories = ['杀菌剂', '杀虫剂', '生长调节剂', '除草剂']
        random.shuffle(categories)
        
        for category in categories:
            if len(recommendations) >= limit:
                break
                
            category_goods = self.recommendation_repo.get_goods_by_category(
                category, None, list(excluded_ids), limit//len(categories) + 1
            )
            
            for goods in category_goods:
                if len(recommendations) >= limit:
                    break
                goods_info = self._format_goods_info(goods)
                goods_info['recommend_reason'] = '为您精选'
                recommendations.append(goods_info)
                excluded_ids.add(goods['goods_id'])
        
        return recommendations
    
    def _format_goods_info(self, goods: Dict[str, Any]) -> Dict[str, Any]:
        """格式化商品信息"""
        return {
            "goods_id": goods.get('goods_id'),
            "goods_no": goods.get('goods_no'),
            "goods_name": goods.get('goods_name'),
            "class_name": goods.get('class_name'),
            "brand_name": goods.get('brand_name'),
            "spec_id": goods.get('spec_id'),
            "spec_name": goods.get('spec_name'),
            "price": float(goods.get('retail_price', 0)),
            "image": goods.get('img_url', ''),
            "stock": goods.get('available_stock', 0),
            "in_stock": goods.get('available_stock', 0) > 0
        } 